package hr.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import hr.entity.DO.*;
import hr.entity.Department;
import hr.entity.Employee;
import hr.entity.Position;
import hr.entity.vo.*;
import hr.entity.vo.request.AddNewDepartmentVo;
import hr.mapper.DepartmentMapper;
import hr.mapper.EmployeesMapper;
import hr.mapper.PositionMapper;
import hr.service.DepartmentsService;
import hr.utils.CommonUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 部门信息表 服务实现类
 * </p>
 *
 * @author zzh
 * @since 2023-12-04
 */
@Service
public class DepartmentsServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentsService {

    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private EmployeesMapper employeesMapper;
    @Autowired
    private PositionMapper positionMapper;


    @Override
    public Department updateDepartment(UpdateDepartmentVo vo) throws Exception {
        CommonUtils.checkObjField(vo, UpdateDepartmentVo.class);
        if (vo.getState() != 0 && vo.getState() != 1) {
            vo.setState(0);
        }
        Department department = new Department(vo.getDepartmentId(), vo.getDepartmentName(), vo.getParentDepartmentId(), vo.getPersonChargeId(), vo.getState(), System.currentTimeMillis(), null);
        int rows = departmentMapper.updateById(department);
        if (rows == 0) {
            throw new Exception("部门信息修改失败");
        }
        return departmentMapper.selectById(department.getDepartmentId());
    }

    @Override
    public List<Position> obtainJobPositionsByDepartmentId(ObtainJobPositionsByDepartmentIdVo vo) {
        QueryWrapper<Position> wrapper = Wrappers.query();
        wrapper.eq("department_id", vo.getDepartmentId()).eq("is_deleted", 0)
                .select("position_id", "position_name", "salary", "position_status", "create_time");
        if (vo.getPageSize() != -1) {
            // 查所有
            wrapper.last("limit " + (vo.getCurrentPage() - 1) * vo.getPageSize() + "," + vo.getPageSize());
        }
        return positionMapper.selectList(wrapper);
    }

    @Override
    public Paging handleUpdateDepartmentPage(ObtainJobPositionsByDepartmentIdVo vo) throws Exception {
        if (CommonUtils.checkParamsObj(vo.getPageSize(), vo.getCurrentPage())) {
            throw new Exception("分页数据参数传递不完整，请确保存在字段 ‘currentPage’ 和 ‘pageSize’");
        }
        if (!vo.checkParamNumberScope()) {
            throw new Exception("分页参数不在合理范围");
        }
        QueryWrapper<Position> wrapper = Wrappers.query();
        wrapper.eq("department_id", vo.getDepartmentId()).eq("is_deleted", 0);
        Long counts = positionMapper.selectCount(wrapper);
        vo.setTotalEntries(counts);
        vo.setTotalPage(vo.getTotalEntries() % vo.getPageSize() == 0 ? vo.getTotalEntries() / vo.getPageSize() : vo.getTotalEntries() % vo.getPageSize() + 1);
        return vo;
    }

    @Override
    public Map<String, Object> handleDepartmentsPositionAndPeople() {
        HashMap<String, Object> map = new HashMap<>();
        List<Map<String, Object>> list = departmentMapper.selectPosition();
        List<Long> positions = new ArrayList<>();
        List<String> departments = new ArrayList<>();
        list.forEach(e -> {
            departments.add((String) e.get("department_name"));
            positions.add((long)(e.get("count")));
        });
        map.put("departments", departments);
        map.put("positions", positions);

        List<Map<String, Object>> list1 = departmentMapper.getDepartmentPeoples();
        ArrayList<String> peopleList = new ArrayList<>();
        list1.forEach(e -> {
            peopleList.add(String.valueOf(e.get("count")));
        });
        map.put("peopleList", peopleList);
        return map;
    }

    @Override
    public List<?> selectAllDepartments(ObtainDepartment obtainDepartment) {
        List<DepartmentEmployeeDO> departmentsList = departmentMapper.selectAllDepartments(
                obtainDepartment.getCurrentPage() > 0 ?
                        (obtainDepartment.getCurrentPage() - 1) * obtainDepartment.getPageSize() : 0,
                obtainDepartment.getPageSize(), obtainDepartment);

        List<DepartmentEmployeeDO> retList = new ArrayList<>();
        HashMap<Long, DepartmentEmployeeDO> memo = new HashMap<>();
        departmentsList.forEach(e -> {
            if (memo.containsKey(e.getDepartmentId())) {
                throw new RuntimeException("存在多个部门拥有相同的主键值 " + e.getDepartmentId());
            } else {
                memo.put(e.getDepartmentId(), e);
            }
        });
        departmentsList.forEach(e -> {
            if (e.getParentDepartmentId() == 0) {
                retList.add(memo.get(e.getDepartmentId()));
            } else if (memo.containsKey(e.getParentDepartmentId())) {
                // 添加孩子节点
                if (memo.get(e.getParentDepartmentId()).getChildren() == null) {
                    memo.get(e.getParentDepartmentId()).setChildren(new ArrayList<>());
                }
                memo.get(e.getParentDepartmentId()).getChildren().add(memo.get(e.getDepartmentId()));
                // memo.get(e.getParentDepartmentId()).getChildren().add(e);
            } else {
                // 非根
                // throw new RuntimeException("遍历部门时，存在一个部门 “" + e.getDepartmentName() + "”无法找到对应上级");
                retList.add(memo.get(e.getDepartmentId()));
            }
        });

        return retList;
    }

    @Override
    public ObtainDepartment getPagingInformation(ObtainDepartment obtainDepartment) {
        ObtainDepartment retObtainDepartment = departmentMapper.selectPagingInformation();
        // 计算总页数
        obtainDepartment.setTotalEntries(retObtainDepartment.getTotalEntries());
        // 计算多少页
        obtainDepartment.setTotalPage(retObtainDepartment.getTotalEntries() % obtainDepartment.getPageSize() == 0 ?
                retObtainDepartment.getTotalEntries() / obtainDepartment.getPageSize() :
                retObtainDepartment.getTotalEntries() / obtainDepartment.getPageSize() + 1);
        return obtainDepartment;
    }

    @Override
    public Department deleteDepartmentById(Integer departmentId) throws Exception {
        // 该部门下面是否有部门 有的话不让删
        if (departmentMapper.checkDepartmentIdCanDelete(departmentId) == 0) {
            throw new Exception("当前部门下存在子部门，不可以删除！");
        }
        Department department = departmentMapper.selectById(departmentId);
        // 不要真删除
        if (departmentMapper.deleteById(departmentId) == 0) {
            throw new Exception("系统错误，删除失败，请稍后再试!");
        }
        return department;
    }

    @Override
    public List<?> getDepartmentRelationshipMap() {
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        class Options {
            /**
             * key
             */
            private Integer value;
            /**
             * name
             */
            private String label;
            private Integer employeeId;
            private String employeeName;
            private String employeePhone;
            List<Options> children;

            public Options(Integer value, String label, List<Options> children) {
                this.value = value;
                this.label = label;
                this.children = children;
            }
        }
        List<DepartmentEmployeeMapDO> list = departmentMapper.selectAllDepartmentsNoArgs();
        HashMap<Integer, Options> memo = new HashMap<>();
        ArrayList<Options> retList = new ArrayList<>();
        list.forEach(e -> {
            memo.put(e.getDepartmentId(), new Options(e.getDepartmentId(), e.getDepartmentName(), e.getEmployeeId(), e.getEmployeeName(), e.getEmployeePhone(), new ArrayList<>()));
        });
        list.forEach(e -> {
            if (e.getParentDepartmentId() == 0) {
                // 根
                retList.add(memo.get(e.getDepartmentId()));
            } else {
                memo.get(e.getParentDepartmentId()).getChildren().add(memo.get(e.getDepartmentId()));
            }
        });
        return retList;
    }

    @Override
    public Department addNewDepartment(AddNewDepartmentVo addNewDepartmentVo) throws Exception {
        if (addNewDepartmentVo.getParentDepartmentId() != null) {
            Department department = departmentMapper.selectById(addNewDepartmentVo.getParentDepartmentId());
            if (department == null) {
                throw new Exception("不存在上级部门");
            }
        }
        if (addNewDepartmentVo.getEmployeeId() != null) {
            // 查负责人 是否存在
            Employee employee = employeesMapper.selectById(addNewDepartmentVo.getEmployeeId());
            if (employee == null) {
                throw new Exception("不存在该负责人");
            }
        }
        if (CommonUtils.checkParams(addNewDepartmentVo.getDepartmentName())) {
            throw new Exception("部门名称不可以为空");
        }

        Department addObj = new Department(null, addNewDepartmentVo.getDepartmentName(), addNewDepartmentVo.getParentDepartmentId(), addNewDepartmentVo.getEmployeeId(), addNewDepartmentVo.getDepartmentState(), System.currentTimeMillis(), null);
        int insert = departmentMapper.insert(addObj);
        if (insert == 0) {
            throw new Exception("添加失败，系统错误");
        }
        return departmentMapper.selectById(addObj.getDepartmentId());
    }

    @Override
    public List<?> getDepartmentHead() {
        return employeesMapper.selectAllForList();
    }
}
